From: Jo-Philipp Wich Date: Thu, 5 Apr 2018 07:32:22 +0000 (+0200) Subject: treewide: filter shell arguments through shellquote() where applicable X-Git-Url: http://git.openwrt.org/%22https:/collectd.org//%22/%22https:/collectd.org/%22?a=commitdiff_plain;h=c0d9c4f3ce7bda19081d0da01a599bec067338a3;p=project%2Fluci.git treewide: filter shell arguments through shellquote() where applicable Signed-off-by: Jo-Philipp Wich --- diff --git a/applications/luci-app-adblock/luasrc/controller/adblock.lua b/applications/luci-app-adblock/luasrc/controller/adblock.lua index 700f187b35..763c0b4b95 100644 --- a/applications/luci-app-adblock/luasrc/controller/adblock.lua +++ b/applications/luci-app-adblock/luasrc/controller/adblock.lua @@ -36,8 +36,8 @@ end function queryData(domain) if domain then luci.http.prepare_content("text/plain") - local cmd = "/etc/init.d/adblock query %q 2>&1" - local util = io.popen(cmd % domain) + local cmd = "/etc/init.d/adblock query %s 2>&1" + local util = io.popen(cmd % util.shellquote(domain)) if util then while true do local line = util:read("*l") diff --git a/applications/luci-app-cshark/luasrc/controller/cshark.lua b/applications/luci-app-cshark/luasrc/controller/cshark.lua index 4d9bbba290..43410a0045 100644 --- a/applications/luci-app-cshark/luasrc/controller/cshark.lua +++ b/applications/luci-app-cshark/luasrc/controller/cshark.lua @@ -53,7 +53,13 @@ function cshark_iface_dump_start(ifname, value, flag, filter) luci.http.prepare_content("text/plain") - local res = os.execute("(/sbin/cshark -i " .. ifname .. " -" .. flag .. " " .. value .. " -p /tmp/cshark-luci.pid " .. filter .. " > /tmp/cshark-luci.out 2>&1) &") + local res = os.execute("(/sbin/cshark -i %s -%s %s -p /tmp/cshark-luci.pid %s > /tmp/cshark-luci.out 2>&1) &" %{ + luci.util.shellquote(ifname), + luci.util.shellquote(flag), + luci.util.shellquote(value), + luci.util.shellquote(filter) + }) + luci.http.write(tostring(res)) end diff --git a/applications/luci-app-ddns/luasrc/controller/ddns.lua b/applications/luci-app-ddns/luasrc/controller/ddns.lua index 3d31e4e0b6..5f4a5118c3 100755 --- a/applications/luci-app-ddns/luasrc/controller/ddns.lua +++ b/applications/luci-app-ddns/luasrc/controller/ddns.lua @@ -301,7 +301,7 @@ function startstop(section, enabled) uci:unload("ddns") -- start ddns-updater for section - local command = luci_helper .. [[ -S ]] .. section .. [[ -- start]] + local command = "%s -S %s -- start" %{ luci_helper, UTIL.shellquote(section) } os.execute(command) NX.nanosleep(3) -- 3 seconds "show time" diff --git a/applications/luci-app-freifunk-diagnostics/luasrc/controller/freifunk/diag.lua b/applications/luci-app-freifunk-diagnostics/luasrc/controller/freifunk/diag.lua index 7bb47612b6..92b3afc80d 100644 --- a/applications/luci-app-freifunk-diagnostics/luasrc/controller/freifunk/diag.lua +++ b/applications/luci-app-freifunk-diagnostics/luasrc/controller/freifunk/diag.lua @@ -33,7 +33,7 @@ function diag_command(cmd, addr) if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then luci.http.prepare_content("text/plain") - local util = io.popen(cmd % addr) + local util = io.popen(cmd % luci.util.shellquote(addr)) if util then while true do local ln = util:read("*l") @@ -52,21 +52,21 @@ function diag_command(cmd, addr) end function diag_ping(addr) - diag_command("ping -c 5 -W 1 %q 2>&1", addr) + diag_command("ping -c 5 -W 1 %s 2>&1", addr) end function diag_traceroute(addr) - diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr) + diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr) end function diag_nslookup(addr) - diag_command("nslookup %q 2>&1", addr) + diag_command("nslookup %s 2>&1", addr) end function diag_ping6(addr) - diag_command("ping6 -c 5 %q 2>&1", addr) + diag_command("ping6 -c 5 %s 2>&1", addr) end function diag_traceroute6(addr) - diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr) + diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr) end diff --git a/applications/luci-app-mwan3/luasrc/controller/mwan3.lua b/applications/luci-app-mwan3/luasrc/controller/mwan3.lua index 64ee9f548c..27dc984eb4 100644 --- a/applications/luci-app-mwan3/luasrc/controller/mwan3.lua +++ b/applications/luci-app-mwan3/luasrc/controller/mwan3.lua @@ -98,7 +98,7 @@ function diagnosticsData(interface, task) function diag_command(cmd, addr) if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then - local util = io.popen(cmd % addr) + local util = io.popen(cmd % ut.shellquote(addr)) if util then while true do local ln = util:read("*l") @@ -138,7 +138,7 @@ function diagnosticsData(interface, task) if task == "ping_gateway" then local gateway = get_gateway(interface) if gateway ~= nil then - diag_command("ping -c 5 -W 1 %q 2>&1", gateway) + diag_command("ping -c 5 -W 1 %s 2>&1", gateway) else luci.http.prepare_content("text/plain") luci.http.write(string.format("No gateway for interface %s found.", interface)) @@ -147,7 +147,7 @@ function diagnosticsData(interface, task) local trackips = uci:get("mwan3", interface, "track_ip") if #trackips > 0 then for i in pairs(trackips) do - diag_command("ping -c 5 -W 1 %q 2>&1", trackips[i]) + diag_command("ping -c 5 -W 1 %s 2>&1", trackips[i]) end else luci.http.write(string.format("No tracking Hosts for interface %s defined.", interface)) @@ -185,10 +185,10 @@ function diagnosticsData(interface, task) luci.http.write(string.format("Routing table %s for interface %s not found", number, interface)) end elseif task == "hotplug_ifup" then - os.execute(string.format("/usr/sbin/mwan3 ifup %s", interface)) + os.execute(string.format("/usr/sbin/mwan3 ifup %s", ut.shellquote(interface))) luci.http.write(string.format("Hotplug ifup sent to interface %s", interface)) elseif task == "hotplug_ifdown" then - os.execute(string.format("/usr/sbin/mwan3 ifdown %s", interface)) + os.execute(string.format("/usr/sbin/mwan3 ifdown %s", ut.shellquote(interface))) luci.http.write(string.format("Hotplug ifdown sent to interface %s", interface)) else luci.http.write("Unknown task") diff --git a/applications/luci-app-olsr/luasrc/controller/olsr.lua b/applications/luci-app-olsr/luasrc/controller/olsr.lua index 229f3d61b3..c5fb2b2a53 100644 --- a/applications/luci-app-olsr/luasrc/controller/olsr.lua +++ b/applications/luci-app-olsr/luasrc/controller/olsr.lua @@ -84,11 +84,11 @@ function action_json() local jsonreq4 local jsonreq6 - local v4_port = uci:get("olsrd", "olsrd_jsoninfo", "port") or 9090 - local v6_port = uci:get("olsrd6", "olsrd_jsoninfo", "port") or 9090 + local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090 + local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090 - jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 " .. v4_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null" ) - jsonreq6 = utl.exec("(echo /status | nc ::1 " .. v6_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null") + jsonreq4 = utl.exec("(echo /status | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v4_port) + jsonreq6 = utl.exec("(echo /status | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" % v6_port) http.prepare_content("application/json") if not jsonreq4 or jsonreq4 == "" then jsonreq4 = "{}" @@ -150,7 +150,7 @@ function action_neigh(json) for _, dev in ipairs(devices) do for _, net in ipairs(dev:get_wifinets()) do local radio = net:get_device() - assoclist[#assoclist+1] = {} + assoclist[#assoclist+1] = {} assoclist[#assoclist]['ifname'] = net:ifname() assoclist[#assoclist]['network'] = net:network()[1] assoclist[#assoclist]['device'] = radio and radio:name() or nil @@ -165,7 +165,7 @@ function action_neigh(json) local mac = "" local ip local neihgt = {} - + if resolve == "1" then hostname = nixio.getnameinfo(v.remoteIP, nil, 100) if hostname then @@ -350,11 +350,11 @@ function fetch_jsoninfo(otable) local IpVersion = uci:get_first("olsrd", "olsrd","IpVersion") local jsonreq4 = "" local jsonreq6 = "" - local v4_port = uci:get("olsrd", "olsrd_jsoninfo", "port") or 9090 - local v6_port = uci:get("olsrd6", "olsrd_jsoninfo", "port") or 9090 + local v4_port = tonumber(uci:get("olsrd", "olsrd_jsoninfo", "port") or "") or 9090 + local v6_port = tonumber(uci:get("olsrd6", "olsrd_jsoninfo", "port") or "") or 9090 - jsonreq4 = utl.exec("(echo /" .. otable .. " | nc 127.0.0.1 " .. v4_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null") - jsonreq6 = utl.exec("(echo /" .. otable .. " | nc ::1 " .. v6_port .. " | sed -n '/^[}{ ]/p') 2>/dev/null") + jsonreq4 = utl.exec("(echo /%s | nc 127.0.0.1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v4_port }) + jsonreq6 = utl.exec("(echo /%s | nc ::1 %d | sed -n '/^[}{ ]/p') 2>/dev/null" %{ otable, v6_port }) local jsondata4 = {} local jsondata6 = {} local data4 = {} diff --git a/applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua b/applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua index 719145b887..ccad531513 100644 --- a/applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua +++ b/applications/luci-app-openvpn/luasrc/model/cbi/openvpn.lua @@ -26,9 +26,9 @@ uci:foreach( "openvpn_recipes", "openvpn_recipe", ) function s.getPID(section) -- Universal function which returns valid pid # or nil - local pid = sys.exec("%s | grep -w %s | grep openvpn | grep -v grep | awk '{print $1}'" % { psstring,section} ) - if pid and #pid > 0 and tonumber(pid) ~= nil then - return tonumber(pid) + local pid = sys.exec("%s | grep -w [o]penvpn(%s)" % { psstring, section }) + if pid and #pid > 0 then + return tonumber(pid:match("^%d+")) else return nil end diff --git a/applications/luci-app-splash/luasrc/controller/splash/splash.lua b/applications/luci-app-splash/luasrc/controller/splash/splash.lua index b4fdbd53a6..af7a3a3c01 100644 --- a/applications/luci-app-splash/luasrc/controller/splash/splash.lua +++ b/applications/luci-app-splash/luasrc/controller/splash/splash.lua @@ -9,7 +9,7 @@ function index() entry({"admin", "services", "splash", "splashtext" }, form("splash/splashtext"), _("Splashtext"), 10) local e - + e = node("splash") e.target = call("action_dispatch") @@ -82,7 +82,7 @@ function action_activate() end end) - if blacklisted then + if blacklisted then luci.http.redirect(luci.dispatcher.build_url("splash" ,"blocked")) else local id = tostring(mac):gsub(':', ''):lower() @@ -106,7 +106,7 @@ function action_status_admin() local uci = luci.model.uci.cursor_state() local macs = luci.http.formvaluetable("save") - local changes = { + local changes = { whitelist = { }, blacklist = { }, lease = { }, @@ -129,22 +129,22 @@ function action_status_admin() if #changes.whitelist > 0 then os.execute("luci-splash whitelist %s >/dev/null" - % table.concat(changes.whitelist)) + % util.shellquote(table.concat(changes.whitelist))) end if #changes.blacklist > 0 then os.execute("luci-splash blacklist %s >/dev/null" - % table.concat(changes.blacklist)) + % util.shellquote(table.concat(changes.blacklist))) end if #changes.lease > 0 then os.execute("luci-splash lease %s >/dev/null" - % table.concat(changes.lease)) + % util.shellquote(table.concat(changes.lease))) end if #changes.remove > 0 then os.execute("luci-splash remove %s >/dev/null" - % table.concat(changes.remove)) + % util.shellquote(table.concat(changes.remove))) end luci.template.render("admin_status/splash", { is_admin = true }) diff --git a/applications/luci-app-splash/root/usr/sbin/luci-splash b/applications/luci-app-splash/root/usr/sbin/luci-splash index 2870dbe6aa..9ec9f3a9e1 100755 --- a/applications/luci-app-splash/root/usr/sbin/luci-splash +++ b/applications/luci-app-splash/root/usr/sbin/luci-splash @@ -36,6 +36,10 @@ function call(cmd) os.execute(cmd) end +function esc(str) + return utl.shellquote(str) +end + function lock() call("lock /var/run/luci_splash.lock") @@ -84,14 +88,14 @@ end function get_physdev(interface) local dev - dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME '" .. interface .. "'; echo $IFNAME")) + dev = utl.trim(sys.exec(". /lib/functions/network.sh; network_get_device IFNAME %s; echo $IFNAME" % esc(interface))) return dev end function get_filter_handle(parent, direction, device, mac) - local input = utl.split(sys.exec('/usr/sbin/tc filter show dev ' .. device .. ' parent ' .. parent) or {}) + local input = utl.split(sys.exec('/usr/sbin/tc filter show dev %s parent %s' %{ esc(device), esc(parent) }) or {}) local tbl = {} local handle for k, v in pairs(input) do @@ -264,7 +268,7 @@ function main(argv) elseif whitelist_macs[mac] then print("Removing %s from whitelist" % mac) remove_whitelist(mac) - whitelist_macs[mac] = nil + whitelist_macs[mac] = nil elseif blacklist_macs[mac] then print("Removing %s from blacklist" % mac) remove_blacklist(mac) @@ -295,7 +299,7 @@ function main(argv) print("\n luci-splash remove \n Remove given address from the lease-, black- or whitelist") print("") - os.exit(1) + os.exit(1) end end @@ -338,8 +342,8 @@ function ipt_delete_all(args, comp, off) off[r.table] = off[r.table] or { } off[r.table][r.chain] = off[r.table][r.chain] or 0 - exec("iptables -t %q -D %q %d 2>/dev/null" - %{ r.table, r.chain, r.index - off[r.table][r.chain] }) + exec("iptables -t %s -D %s %d 2>/dev/null" + %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] }) off[r.table][r.chain] = off[r.table][r.chain] + 1 end @@ -353,8 +357,8 @@ function ipt6_delete_all(args, comp, off) off[r.table] = off[r.table] or { } off[r.table][r.chain] = off[r.table][r.chain] or 0 - exec("ip6tables -t %q -D %q %d 2>/dev/null" - %{ r.table, r.chain, r.index - off[r.table][r.chain] }) + exec("ip6tables -t %s -D %s %d 2>/dev/null" + %{ esc(r.table), esc(r.chain), r.index - off[r.table][r.chain] }) off[r.table][r.chain] = off[r.table][r.chain] + 1 end @@ -460,13 +464,13 @@ function remove_whitelist_tc(mac) end local handle = get_filter_handle('ffff:', 'src', device, mac) if handle then - exec('tc filter del dev "%s" parent ffff: protocol ip prio 1 handle %s u32' % { device, handle }) + exec('tc filter del dev %s parent ffff: protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) }) else print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device }) end local handle = get_filter_handle('1:', 'dest', device, mac) if handle then - exec('tc filter del dev "%s" parent 1:0 protocol ip prio 1 handle %s u32' % { device, handle }) + exec('tc filter del dev %s parent 1:0 protocol ip prio 1 handle %s u32' % { esc(device), esc(handle) }) else print('Warning! Could not get a handle for %s parent 1:0 on interface %s' % { mac, device }) end @@ -492,37 +496,37 @@ function add_lease_rule(mac, ipaddr, device) id = get_id(ipaddr) end - exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j RETURN" % mac) + exec("iptables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j RETURN" % esc(mac)) -- Mark incoming packets to a splashed host -- for ipv4 - by iptables and destination if id and device then - exec("iptables -t mangle -I luci_splash_mark_in -d %q -j MARK --set-mark 0x1%s -m comment --comment %s" % {ipaddr, id, mac:upper()}) + exec("iptables -t mangle -I luci_splash_mark_in -d %s -j MARK --set-mark 0x1%s -m comment --comment %s" % { esc(ipaddr), esc(id), esc(mac:upper())}) end --for ipv6: need to use the mac here if has_ipv6 then - exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %q -j MARK --set-mark 79" % mac) + exec("ip6tables -t mangle -I luci_splash_mark_out -m mac --mac-source %s -j MARK --set-mark 79" % esc(mac)) if id and device and tonumber(limit_down) then - exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % {device, mac:lower(), id}) + exec("tc filter add dev %s parent 1:0 protocol ipv6 prio 1 u32 match ether dst %s classid 1:%s" % { esc(device), esc(mac:lower()), esc(id) }) end end if device and tonumber(limit_up) > 0 then - exec('tc filter add dev "%s" parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % {device, mac, limit_up}) + exec('tc filter add dev %s parent ffff: protocol all prio 2 u32 match ether src %s police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(mac), esc(limit_up) }) end if id and device and tonumber(limit_down) > 0 then - exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { device, id, limit_down }) - exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { device, id }) + exec("tc class add dev %s parent 1: classid 1:0x%s htb rate %skbit" % { esc(device), esc(id), esc(limit_down) }) + exec("tc qdisc add dev %s parent 1:%s sfq perturb 10" % { esc(device), esc(id) }) end - exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) - exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac) + exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac)) + exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac)) if has_ipv6 then - exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) + exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac)) end end @@ -548,32 +552,32 @@ function remove_lease_rule(mac, ipaddr, device, limit_up, limit_down) if device and tonumber(limit_up) > 0 then local handle = get_filter_handle('ffff:', 'src', device, mac) if handle then - exec('tc filter del dev "%s" parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % {device, handle, limit_up}) + exec('tc filter del dev %s parent ffff: protocol all prio 2 handle %s u32 police rate %skbit mtu 6k burst 6k drop' % { esc(device), esc(handle), esc(limit_up) }) else print('Warning! Could not get a handle for %s parent :ffff on interface %s' % { mac, device }) end end -- remove clients class if device and id then - exec('tc class del dev "%s" classid 1:%s' % {device, id}) - exec('tc filter del dev "%s" parent 1:0 prio 1' % device) -- ipv6 rule - --exec('tc qdisc del dev "%s" parent 1:%s sfq perturb 10' % { device, id }) + exec('tc class del dev %s classid 1:%s' % { esc(device), esc(id) }) + exec('tc filter del dev %s parent 1:0 prio 1' % esc(device)) -- ipv6 rule + --exec('tc qdisc del dev %s parent 1:%s sfq perturb 10' % { esc(device), esc(id) }) end end -- Add whitelist rules function add_whitelist_rule(mac) - exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) - exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %q -j RETURN" % mac) + exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac)) + exec("iptables -t nat -I luci_splash_leases -m mac --mac-source %s -j RETURN" % esc(mac)) if has_ipv6 then - exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j RETURN" % mac) + exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j RETURN" % esc(mac)) end uci:foreach("luci_splash", "iface", function(s) local device = get_physdev(s['.name']) if device and device ~= "" then - exec('tc filter add dev "%s" parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { device, mac }) - exec('tc filter add dev "%s" parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { device, mac }) + exec('tc filter add dev %s parent ffff: protocol ip prio 1 u32 match ether src %s police pass' % { esc(device), esc(mac) }) + exec('tc filter add dev %s parent 1:0 protocol ip prio 1 u32 match ether dst %s classid 1:1' % { esc(device), esc(mac) }) end end) end @@ -581,9 +585,9 @@ end -- Add blacklist rules function add_blacklist_rule(mac) - exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac) + exec("iptables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac)) if has_ipv6 then - exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %q -j DROP" % mac) + exec("ip6tables -t filter -I luci_splash_filter -m mac --mac-source %s -j DROP" % esc(mac)) end end @@ -596,15 +600,15 @@ function sync() -- Current leases in state files local leases = uci:get_all("luci_splash_leases") - + -- Convert leasetime to seconds local leasetime = tonumber(uci:get("luci_splash", "general", "leasetime")) * 3600 - + -- Clean state file uci:load("luci_splash_leases") uci:revert("luci_splash_leases") - + local blackwhitelist = uci:get_all("luci_splash") local whitelist_total = 0 local whitelist_online = 0 @@ -628,7 +632,7 @@ function sync() end -- Rewrite state - uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), { + uci:section("luci_splash_leases", "lease", convert_mac_to_secname(v.mac), { mac = v.mac, ipaddr = v.ipaddr, device = v.device, @@ -639,7 +643,7 @@ function sync() end end end - + -- Whitelist, Blacklist for _, s in utl.spairs(blackwhitelist, function(a,b) return blackwhitelist[a][".type"] > blackwhitelist[b][".type"] end @@ -666,7 +670,7 @@ function sync() -- ToDo: -- include a new field "leases_online" in stats to differ between active clients and leases: - -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later: + -- update_stats(leasecount, leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) later: update_stats(leases_online, whitelist_online, whitelist_total, blacklist_online, blacklist_total) uci:save("luci_splash_leases") diff --git a/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua b/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua index e29a2e17d9..47e1696ece 100644 --- a/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua +++ b/applications/luci-app-statistics/luasrc/statistics/rrdtool.lua @@ -87,7 +87,7 @@ function Graph._rrdtool( self, def, rrd ) fs.mkdirr( dir ) -- construct commandline - local cmdline = "rrdtool graph" + local cmdline = { "rrdtool", "graph" } -- copy default arguments to def stack for i, opt in ipairs(self.args) do @@ -102,15 +102,11 @@ function Graph._rrdtool( self, def, rrd ) opt = opt:gsub( "{file}", rrd ) end - if opt:match("[^%w]") then - cmdline = cmdline .. " '" .. opt .. "'" - else - cmdline = cmdline .. " " .. opt - end + cmdline[#cmdline+1] = luci.util.shellquote(opt) end -- execute rrdtool - local rrdtool = io.popen( cmdline ) + local rrdtool = io.popen(table.concat(cmdline, " ")) rrdtool:close() end diff --git a/applications/luci-app-tinyproxy/luasrc/view/tinyproxy_status.htm b/applications/luci-app-tinyproxy/luasrc/view/tinyproxy_status.htm index d43a887b07..2ba9dddb8e 100644 --- a/applications/luci-app-tinyproxy/luasrc/view/tinyproxy_status.htm +++ b/applications/luci-app-tinyproxy/luasrc/view/tinyproxy_status.htm @@ -13,7 +13,11 @@ if luci.http.formvalue("frame") == "1" then end) local data = false - local wget = io.popen("wget -qO- http://%s:%s" % { addr, port }) + local wget = io.popen("wget -qO- http://%s:%s" %{ + luci.util.shellquote(addr), + luci.util.shellquote(port) + }) + if wget then while true do local l = wget:read("*l") @@ -30,7 +34,10 @@ if luci.http.formvalue("frame") == "1" then if not data then luci.http.write(translate("Failed to retrieve statistics from url:")) - luci.http.write(" http://%s:%s" % { addr, port }) + luci.http.write(" http://%s:%s" %{ + luci.util.pcdata(addr), + luci.util.pcdata(port) + }) end return @@ -43,7 +50,7 @@ end

<%:Tinyproxy Status%>

- +
diff --git a/applications/luci-app-upnp/luasrc/controller/upnp.lua b/applications/luci-app-upnp/luasrc/controller/upnp.lua index e485708f0e..95a0ef4862 100644 --- a/applications/luci-app-upnp/luasrc/controller/upnp.lua +++ b/applications/luci-app-upnp/luasrc/controller/upnp.lua @@ -21,7 +21,7 @@ end function act_status() local uci = luci.model.uci.cursor() local lease_file = uci:get("upnpd", "config", "upnp_lease_file") - + local ipt = io.popen("iptables --line-numbers -t nat -xnvL MINIUPNPD 2>/dev/null") if ipt then local upnpf = lease_file and io.open(lease_file, "r") @@ -39,7 +39,7 @@ function act_status() num = tonumber(num) extport = tonumber(extport) intport = tonumber(intport) - + if upnpf then local uln = upnpf:read("*l") if uln then descr = uln:match(string.format("^%s:%d:%s:%d:%%d*:(.*)$", proto:upper(), extport, intaddr, intport)) end @@ -76,7 +76,7 @@ function act_delete(num) local lease_file = uci:get("upnpd", "config", "upnp_lease_file") if lease_file and nixio.fs.access(lease_file) then - luci.sys.call("sed -i -e '%dd' %q" %{ idx, lease_file }) + luci.sys.call("sed -i -e '%dd' %s" %{ idx, luci.util.shellquote(lease_file) }) end luci.http.status(200, "OK") diff --git a/applications/luci-app-vnstat/luasrc/view/vnstat.htm b/applications/luci-app-vnstat/luasrc/view/vnstat.htm index 2b8d9ff9c9..42d7d2404b 100644 --- a/applications/luci-app-vnstat/luasrc/view/vnstat.htm +++ b/applications/luci-app-vnstat/luasrc/view/vnstat.htm @@ -21,12 +21,13 @@ style = (style and #style > 0) and style or "s" -- render image -- if iface then - style = style:gsub("[^%w]", "") - iface = iface:gsub("[^%w%.%-%_]", "") - luci.http.prepare_content("image/png") - local png = io.popen("vnstati -i '%s' '-%s' -o -" % { iface, style }) + local png = io.popen("vnstati -i %s -%s -o -" %{ + utl.shellquote(iface), + utl.shellquote(style) + }) + luci.http.write(png:read("*a")) png:close() @@ -89,7 +90,7 @@ dbdir = dbdir or "/var/lib/vnstat" <% end end - end + end %> <% if empty then %> diff --git a/applications/luci-app-wol/luasrc/model/cbi/wol.lua b/applications/luci-app-wol/luasrc/model/cbi/wol.lua index d40dde0178..43b87dda9c 100644 --- a/applications/luci-app-wol/luasrc/model/cbi/wol.lua +++ b/applications/luci-app-wol/luasrc/model/cbi/wol.lua @@ -1,6 +1,7 @@ -- Copyright 2010 Jo-Philipp Wich -- Licensed to the public under the Apache License 2.0. +local utl = require "luci.util" local sys = require "luci.sys" local ipc = require "luci.ip" local fs = require "nixio.fs" @@ -69,8 +70,8 @@ function host.write(self, s, val) if util == "/usr/bin/etherwake" then local iface = luci.http.formvalue("cbid.wol.1.iface") local broadcast = luci.http.formvalue("cbid.wol.1.broadcast") - cmd = "%s -D%s %s %q" %{ - util, (iface ~= "" and " -i %q" % iface or ""), + cmd = "%s -D%s %s %q 2>&1" %{ + util, (iface ~= "" and " -i %s" % utl.shellquote(iface) or ""), (broadcast == "1" and " -b" or ""), mac } else @@ -78,7 +79,7 @@ function host.write(self, s, val) end local msg = "

%s

%s

" %{ - translate("Starting WoL utility:"), cmd + translate("Starting WoL utility:"), utl.pcdata(cmd) } local p = io.popen(cmd .. " 2>&1") diff --git a/modules/luci-base/luasrc/model/ipkg.lua b/modules/luci-base/luasrc/model/ipkg.lua index e653b03465..e27ea52895 100644 --- a/modules/luci-base/luasrc/model/ipkg.lua +++ b/modules/luci-base/luasrc/model/ipkg.lua @@ -20,12 +20,14 @@ module "luci.model.ipkg" -- Internal action function local function _action(cmd, ...) - local pkg = "" + local cmdline = { ipkg, cmd } + + local k, v for k, v in pairs({...}) do - pkg = pkg .. " '" .. v:gsub("'", "") .. "'" + cmdline[#cmdline+1] = util.shellquote(v) end - local c = "%s %s %s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" %{ ipkg, cmd, pkg } + local c = "%s >/tmp/opkg.stdout 2>/tmp/opkg.stderr" % table.concat(cmdline, " ") local r = os.execute(c) local e = fs.readfile("/tmp/opkg.stderr") local o = fs.readfile("/tmp/opkg.stdout") @@ -74,17 +76,17 @@ local function _parselist(rawdata) end -- Internal lookup function -local function _lookup(act, pkg) - local cmd = ipkg .. " " .. act +local function _lookup(cmd, pkg) + local cmdline = { ipkg, cmd } if pkg then - cmd = cmd .. " '" .. pkg:gsub("'", "") .. "'" + cmdline[#cmdline+1] = util.shellquote(pkg) end -- OPKG sometimes kills the whole machine because it sucks -- Therefore we have to use a sucky approach too and use -- tmpfiles instead of directly reading the output local tmpfile = os.tmpname() - os.execute(cmd .. (" >%s 2>/dev/null" % tmpfile)) + os.execute("%s >%s 2>/dev/null" %{ table.concat(cmdline, " "), tmpfile }) local data = _parselist(io.lines(tmpfile)) os.remove(tmpfile) @@ -123,9 +125,12 @@ end -- List helper local function _list(action, pat, cb) - local fd = io.popen(ipkg .. " " .. action .. - (pat and (" '%s'" % pat:gsub("'", "")) or "")) + local cmdline = { ipkg, action } + if pat then + cmdline[#cmdline+1] = util.shellquote(pat) + end + local fd = io.popen(table.concat(cmdline, " ")) if fd then local name, version, sz, desc while true do diff --git a/modules/luci-base/luasrc/model/uci.lua b/modules/luci-base/luasrc/model/uci.lua index 3208f3b372..bbd9b4cfbf 100644 --- a/modules/luci-base/luasrc/model/uci.lua +++ b/modules/luci-base/luasrc/model/uci.lua @@ -407,7 +407,7 @@ function apply(self, configlist, command) return { "/sbin/luci-reload", unpack(configlist) } else return os.execute("/sbin/luci-reload %s >/dev/null 2>&1" - % table.concat(configlist, " ")) + % util.shellquote(table.concat(configlist, " "))) end end diff --git a/modules/luci-base/luasrc/sys.lua b/modules/luci-base/luasrc/sys.lua index 12b20e4c38..823e20770c 100644 --- a/modules/luci-base/luasrc/sys.lua +++ b/modules/luci-base/luasrc/sys.lua @@ -87,10 +87,10 @@ end function httpget(url, stream, target) if not target then local source = stream and io.popen or luci.util.exec - return source("wget -qO- '"..url:gsub("'", "").."'") + return source("wget -qO- %s" % luci.util.shellquote(url)) else - return os.execute("wget -qO '%s' '%s'" % - {target:gsub("'", ""), url:gsub("'", "")}) + return os.execute("wget -qO %s %s" % + {luci.util.shellquote(target), luci.util.shellquote(url)}) end end @@ -443,18 +443,11 @@ function user.checkpasswd(username, pass) end function user.setpasswd(username, password) - if password then - password = password:gsub("'", [['"'"']]) - end - - if username then - username = username:gsub("'", [['"'"']]) - end - - return os.execute( - "(echo '" .. password .. "'; sleep 1; echo '" .. password .. "') | " .. - "passwd '" .. username .. "' >/dev/null 2>&1" - ) + return os.execute("(echo %s; sleep 1; echo %s) | passwd %s >/dev/null 2>&1" %{ + luci.util.shellquote(password), + luci.util.shellquote(password), + luci.util.shellquote(username) + }) end diff --git a/modules/luci-base/luasrc/tools/status.lua b/modules/luci-base/luasrc/tools/status.lua index 1c4038735f..06a9ad4154 100644 --- a/modules/luci-base/luasrc/tools/status.lua +++ b/modules/luci-base/luasrc/tools/status.lua @@ -187,7 +187,9 @@ function switch_status(devs) local switches = { } for dev in devs:gmatch("[^%s,]+") do local ports = { } - local swc = io.popen("swconfig dev '%s' show" % dev:gsub("'", ""), "r") + local swc = io.popen("swconfig dev %s show" + % luci.util.shellquote(dev), "r") + if swc then local l repeat diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/network.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/network.lua index 33f6a67038..070a9e6167 100644 --- a/modules/luci-mod-admin-full/luasrc/controller/admin/network.lua +++ b/modules/luci-mod-admin-full/luasrc/controller/admin/network.lua @@ -289,7 +289,8 @@ function iface_reconnect(iface) local netmd = require "luci.model.network".init() local net = netmd:get_network(iface) if net then - luci.sys.call("env -i /sbin/ifup %q >/dev/null 2>/dev/null" % iface) + luci.sys.call("env -i /sbin/ifup %s >/dev/null 2>/dev/null" + % luci.util.shellquote(iface)) luci.http.status(200, "Reconnected") return end @@ -301,7 +302,8 @@ function iface_shutdown(iface) local netmd = require "luci.model.network".init() local net = netmd:get_network(iface) if net then - luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface) + luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null" + % luci.util.shellquote(iface)) luci.http.status(200, "Shutdown") return end @@ -313,7 +315,8 @@ function iface_delete(iface) local netmd = require "luci.model.network".init() local net = netmd:del_network(iface) if net then - luci.sys.call("env -i /sbin/ifdown %q >/dev/null 2>/dev/null" % iface) + luci.sys.call("env -i /sbin/ifdown %s >/dev/null 2>/dev/null" + % luci.util.shellquote(iface)) luci.http.redirect(luci.dispatcher.build_url("admin/network/network")) netmd:commit("network") netmd:commit("wireless") @@ -389,7 +392,7 @@ function diag_command(cmd, addr) if addr and addr:match("^[a-zA-Z0-9%-%.:_]+$") then luci.http.prepare_content("text/plain") - local util = io.popen(cmd % addr) + local util = io.popen(cmd % luci.util.shellquote(addr)) if util then while true do local ln = util:read("*l") @@ -408,21 +411,21 @@ function diag_command(cmd, addr) end function diag_ping(addr) - diag_command("ping -c 5 -W 1 %q 2>&1", addr) + diag_command("ping -c 5 -W 1 %s 2>&1", addr) end function diag_traceroute(addr) - diag_command("traceroute -q 1 -w 1 -n %q 2>&1", addr) + diag_command("traceroute -q 1 -w 1 -n %s 2>&1", addr) end function diag_nslookup(addr) - diag_command("nslookup %q 2>&1", addr) + diag_command("nslookup %s 2>&1", addr) end function diag_ping6(addr) - diag_command("ping6 -c 5 %q 2>&1", addr) + diag_command("ping6 -c 5 %s 2>&1", addr) end function diag_traceroute6(addr) - diag_command("traceroute6 -q 1 -w 2 -n %q 2>&1", addr) + diag_command("traceroute6 -q 1 -w 2 -n %s 2>&1", addr) end diff --git a/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua b/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua index 4b03a18863..3a1c169f21 100644 --- a/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua +++ b/modules/luci-mod-admin-full/luasrc/controller/admin/status.lua @@ -62,7 +62,9 @@ end function action_bandwidth(iface) luci.http.prepare_content("application/json") - local bwc = io.popen("luci-bwc -i '%s' 2>/dev/null" % iface:gsub("'", "")) + local bwc = io.popen("luci-bwc -i %s 2>/dev/null" + % luci.util.shellquote(iface)) + if bwc then luci.http.write("[") @@ -80,7 +82,9 @@ end function action_wireless(iface) luci.http.prepare_content("application/json") - local bwc = io.popen("luci-bwc -r '%s' 2>/dev/null" % iface:gsub("'", "")) + local bwc = io.popen("luci-bwc -r %s 2>/dev/null" + % luci.util.shellquote(iface)) + if bwc then luci.http.write("[") diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/vlan.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/vlan.lua index 89a73a5ca8..b52dff13ac 100644 --- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/vlan.lua +++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/vlan.lua @@ -5,6 +5,7 @@ m = Map("network", translate("Switch"), translate("The network ports on this device can be combined to several VLANs in which computers can communicate directly with each other. VLANs are often used to separate different network segments. Often there is by default one Uplink port for a connection to the next greater network like the internet and other ports for a local network.")) local fs = require "nixio.fs" +local ut = require "luci.util" local nw = require "luci.model.network" local switches = { } @@ -74,7 +75,7 @@ m.uci:foreach("network", "switch", end -- Parse some common switch properties from swconfig help output. - local swc = io.popen("swconfig dev %q help 2>/dev/null" % switch_name) + local swc = io.popen("swconfig dev %s help 2>/dev/null" % ut.shellquote(switch_name)) if swc then local is_port_attr = false diff --git a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua index c0bb380307..a574d35979 100644 --- a/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua +++ b/modules/luci-mod-admin-full/luasrc/model/cbi/admin_network/wifi.lua @@ -63,7 +63,7 @@ function m.parse(map) Map.parse(map) if m:get(wdev:name(), "type") == "mac80211" and new_cc and new_cc ~= old_cc then - luci.sys.call("iw reg set %q" % new_cc) + luci.sys.call("iw reg set %s" % ut.shellquote(new_cc)) luci.http.redirect(luci.dispatcher.build_url("admin/network/wireless", arg[1])) return end